// type isTwo<T> = T extends 2 ? true : false;

// type res = isTwo<1>;
// type res2 = isTwo<2>;

// ------------------------------------

// 提取元组类型的第一个元素

// type First<Tuple extends unknown[]> = Tuple extends [infer T, ...infer R] ? T : never;

// type res = First<[1, 2, 3]>; // type res = 1

// ------------------------------------

// 对象、class 在 TypeScript 对应的类型是索引类型（Index Type），那么如何对索引类型作修改呢？

// type MapType<T> = {
//   [Key in keyof T]?: T[Key];
// };

// function getObjValue<T, K extends keyof T>(obj: T, key: K) {
//   return obj[key];
// }

// const res = getObjValue({ a: 1, b: 2 }, 'a');

// type MapType<T> = {
//   [Key in keyof T]: [T[Key], T[Key], T[Key]];
// };

// type res = MapType<{ a: 1; b: 2 }>;

// 除了值可以变化，索引也可以做变化，用 as 运算符，叫做重映射。

type MapType<T> = {
  [Key in keyof T as `${Key & string}|${Key & string}|${Key & string}`]: [T[Key], T[Key], T[Key]];
};

type res = MapType<{ a: 1; b: 2 }>;

/**
 * & string 说明:
 *
 * 因为索引类型（对象、class 等）可以用 string、number 和 symbol 作为 key，这里 keyof T 取出的索引就是 string | number | symbol 的联合类型，和 string 取交叉部分就只剩下 string 了。就像前面所说，【交叉类型会把同一类型做合并，不同类型舍弃】。
 */

export {};
